package com.boarsoft.web.login;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.boarsoft.bean.LogonI;
import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.auth.TokenAuth;
import com.boarsoft.common.Util;

@Component("logonArgResolver")
public class LogonArgResolver implements HandlerMethodArgumentResolver {

	@Autowired
	@Lazy
	private TokenAuth tokenAuth;

	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		if (parameter.getParameterAnnotation(Logined.class) != null) {
			if (parameter.getParameterType() != LogonI.class) {
				throw new IllegalArgumentException("@Logined only support LogonI argument");
			}
			// 如果该参数注解有@Logined才会执行下面的resolveArgument方法
			return true;
		}
		return false;
	}

	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
			WebDataBinderFactory binderFactory) throws Exception {
		HttpServletRequest rq = (HttpServletRequest) webRequest.getNativeRequest();
		// 如果有传TOKEN，根据TOKEN取UID，否则检查COOKIE(会话)，检查执行权限
		String token = rq.getParameter("token");
		if (Util.strIsEmpty(token)) {
			token = this.getCookie(rq, "token");
		}
		// TODO 改成直接到redis中找？
		ReplyInfo<Object> ri = tokenAuth.check(token);
		if (ri.isSuccess()) {
			return ri.getData(); // Logon
		}
		return null;
	}

	/**
	 * 取得某个Cookie值
	 * 
	 * @param request
	 * @param key
	 * @return
	 */
	private String getCookie(HttpServletRequest request, String key) {
		Cookie[] ca = request.getCookies();
		if (ca == null || ca.length < 1)
			return null;
		for (Cookie c : ca) {
			if (c.getName().equals(key)) {
				return c.getValue();
			}
		}
		return null;
	}
}